
import 'package:flutter/material.dart';
import 'package:xsdk_flutter/xsdk/framework/bean/x_bean_menu.dart';
import 'package:xsdk_flutter/xsdk/framework/page/x_page_state.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_color.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_image.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_log.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_string.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_style.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_widget.dart';


/*
TabBar,类似android的Tab+Fragment
TabBar和BottomNavigationBar一次只能使用一个
 */
abstract class XPageTabBarTabViewState extends XPageState {

  bool isTabBarScrollable;
  TabAlignment tabAlignment;

  XPageTabBarTabViewState(
      {
        super.isKeepPageState=false,
        super.xTag,
        super.handleAndFinishPageFunction,
        this.isTabBarScrollable=true,
        this.tabAlignment=TabAlignment.start,
      }
      );

  /*
  注意:tabBar是一次加载所有对应tabView的Widget:
  1.传入Widget,适用一起加载所有页面,则可以传入widget
  2.传入XStatefulWidget(()=>XState()); 或 XPage(()=>);
  针对tab过多情况,限制tabView中同时过多请求api,要使用state,利用state的生命周期机制,拦截未进入前台显示的页面先不执行其生命周期方法,
  切换tab时,当前的state会执行onDestroy()方法,返回上一个tab会重新创建执行oncreate()方法

   */
  @required
  Widget getTabViewWidget(XBeanMenuItem tabItem);

  @required
  void notifyTabControllerChangeCallback(int tabIndex);

  /////////////////////////////////////////////////////

  //更新tab数据
  void updateXTabBar(
      {
        List<XBeanMenuItem>? items,
        TextStyle? tabSelectTextStyle,
        TextStyle? tabUnSelectTextStyle,
      }
      ){



    setState(() {
      //
      widget.currentTabIndex=0;
      widget.currentTabItem=null;
      //
      _tabSelectTextStyle=tabSelectTextStyle;
      _tabUnSelectTextStyle=tabUnSelectTextStyle;

      //
      _listTabItems.clear();
      if(items!=null&& items.isNotEmpty){
        widget.currentTabItem=items[0];
        _listTabItems.addAll(items);
      }

    });

  }

  //手动切换tabView(tabBar已自动关联tabView)
  void changeTab(int index) {

    if(tabController==null) return;

    if (index < 0
        || index >= tabController!.length
        || index == tabController!.index) return;
    //
    tabController!.animateTo(index);
  }

  void changeNextTab() {

    if(tabController==null) return;

    if (tabController!.index == tabController!.length-1){
      tabController!.animateTo(0);
    }else{
      tabController!.animateTo(tabController!.index+1);
    }
  }


  //重写设置////////////////////////////////////////////////////


  //是否在底部显示指示器(引导页使用,同时隐藏tabBar)
  bool getIsShowBottomTabPageSelector(){
    return false;
  }

  //tabBar背景颜色
  Color getTabBarBackgroundColor(){
    return Colors.white;
  }


  /////////////////////////////////////////////


  @override
  Widget getBodyWidget(BuildContext context) {

    if(_listTabItems.isEmpty){
      return XWidgetUtils.getLayoutContainer();
    }

    //先释放旧的controller和监听
    tabController?.dispose();

    //注意:这里不使用DefaultTabController套在最外层方式,声明切换length的个数,保证与listTabItems个数一致，否则会报错。
    tabController=TabController(
      initialIndex: widget.currentTabIndex,
      animationDuration: const Duration(milliseconds: 200),
      //注意:TabController初始化声明length只能设置一次,不能更改,因此需要预先加载确认tab的个数
      length:_listTabItems.length,
      vsync: this,
    );


    //添加监听
    tabController?.addListener((){
      widget.currentTabIndex=tabController?.index??0;

      XLogUtils.printLog('---监听tabController,widget.currentTabIndex=${widget.currentTabIndex}');

      if(_listTabItems.isNotEmpty){
        widget.currentTabItem=_listTabItems[widget.currentTabIndex];
      }

      notifyTabControllerChangeCallback(widget.currentTabIndex);
    });

    //页面浮层结构
    List<Widget> stackLayout = [];

    List<Widget> tabWidgets = [];

    if(!getIsShowBottomTabPageSelector()){
      //显示tabBar
      tabWidgets.add(
          XWidgetUtils.getLayoutContainer(
            //是否居中显示,否则靠左
            child: _createTabBar(),
            height: 46,
            width: double.infinity,
            backgroundColor: getTabBarBackgroundColor(),
          )
      );
    }
    //tabView
    tabWidgets.add(XWidgetUtils.getLayoutExpanded(_createTabBarView()));

    //
    stackLayout.add(
        XWidgetUtils.getLayoutContainer(
            child: XWidgetUtils.getLayoutColumn(
                children: tabWidgets
            )
        )
    );

    //tabView底部指示器(引导页使用)
    if(getIsShowBottomTabPageSelector()){
      stackLayout.add(
          XWidgetUtils.getLayoutPositioned(
              bottom: 20,
              left: 0,
              right: 0,
              child: XWidgetUtils.getLayoutAlign(
                  alignment: Alignment.bottomCenter,
                  child: TabPageSelector(
                    controller: tabController,
                    selectedColor: Colors.white70,
                    indicatorSize: 7,
                    color: Colors.white30,
                  ))
          )
      );
    }


    return XWidgetUtils.getLayoutStack(children:stackLayout);
  }

  /*
  注意:
  在此base页面父类中集成TabBar支持,但需要继承XPageTabBottomNavigationBarState使用;
  而不是普通的StatelessWidget(每次切换都会重新更新)
   */
  //tabBar背景
  //注意:这里不使用DefaultTabController套在最外层,使用TabController实例传入tab
  TabController? tabController;
  TextStyle? _tabSelectTextStyle;
  TextStyle? _tabUnSelectTextStyle;

  final List<XBeanMenuItem> _listTabItems=[];//注意:item不能为null


  /*
  设置TabItemView(Tab)
  注意:设置Tab时,其text与child不能同时设置,否则报错;图标显示优先文字,二选一,避免撑破高度(tab上下结构)
   */
  Tab _getTabBarItemWidget(XBeanMenuItem tabItem){
    if(!XStringUtils.isEmpty(tabItem.image)){
      return Tab(
        //text: tabItem.text,
          icon: XImageUtils.getImageWidgetWithAsset(
            tabItem.image!,
            width: tabItem.imageWidth,
            height: tabItem.imageHeight,
            //color: XColorUtils.color666666,
          )
      );
    }else{
      return Tab(
        text: tabItem.text,
        //icon: Icon(tabItem.icon),
      );
    }
  }

  //创建TabBar(私有,内部实现)
  TabBar _createTabBar() {
    return TabBar(
      //注意:使用DefaultTabController时不能设置TabBar的controller,否则会报错
      controller: tabController,
      isScrollable:isTabBarScrollable,
      tabAlignment:tabAlignment,
      dividerColor: XColorUtils.dividerColor,
      dividerHeight: 0.5,
      //splashBorderRadius:BorderRadius.circular(2),
      indicatorWeight:4,//indicatorWeight指示器高
      indicatorSize: TabBarIndicatorSize.label,//indicatorSize指示器大小计算方式，TabbarIndicatorSize.label跟文字等宽 TabbarIndicatorSize.tab跟每个tab等宽
      indicatorPadding: XWidgetUtils.getEdgeInsets(5, 36, 5, 6),//indicatorPadding指示器边距【EdgensetsGeometry】
      indicator: XWidgetUtils.getBoxDecoration(
        backgroundColor: XColorUtils.appMainColor,
        border:Border.all(color:XColorUtils.appMainColor, style: BorderStyle.solid, width:1),
        borderRadius: const BorderRadius.all(Radius.circular(2)),
      ),
      indicatorColor:XColorUtils.appMainColor,//指示器颜色
      //选中
      labelStyle: _tabSelectTextStyle??XStyleUtils.getTextStyle(
        fontSize: 14,
        fontWeight: FontWeight.bold,
        color: XColorUtils.appMainColor,
      ),
      labelColor: XColorUtils.appMainColor,
      //未选中
      unselectedLabelStyle: _tabUnSelectTextStyle??XStyleUtils.getTextStyle(
          fontSize: 14,
          color: XColorUtils.color666666
      ),
      unselectedLabelColor: XColorUtils.color666666,
      //使用map将原始数据list转换成Tab的list
      tabs: _listTabItems.map((XBeanMenuItem tabItemData) {
        return XWidgetUtils.getLayoutContainer(
          alignment: Alignment.center,
          child:_getTabBarItemWidget(tabItemData),
        );
      }).toList(),
    );
  }

  //创建tabView(私有,内部实现)
  TabBarView _createTabBarView() {
    return TabBarView(
      //注意:使用DefaultTabController时不能设置TabBar的controller,否则会报错
      controller: tabController,
      children: _listTabItems.map((XBeanMenuItem tabItemData) {
        return getTabViewWidget(tabItemData);
      }).toList(),
    );
  }

  /////////////////////////////////////////////////////////////////////////

  @override
  void dispose() {
    //手动释放tabBar的controller
    tabController?.dispose();
    super.dispose();
  }

}